﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Drawing;
using System.Drawing.Imaging;
using System.Web;

namespace Company.StudyClub.BLL.Common
{
    /// <summary>
    /// 缩图处理类
    /// </summary>
    public class CutImage
    {
        #region 构造函数
        public CutImage()
        {

        }
        #endregion

        #region 私有成员
        private int width;
        private int height;
        private int size;
        private string errMSG;
        #endregion

        #region 公共属性
        /// <summary>
        /// 图片宽度
        /// </summary>
        public int Width
        {
            get { return width; }
            set { width = value; }
        }
        /// <summary>
        /// 图片高度
        /// </summary>
        public int Height
        {
            get { return height; }
            set { height = value; }
        }
        /// <summary>
        /// 图片尺寸
        /// </summary>
        public int Size
        {
            get { return size; }
            set { size = value; }
        }
        /// <summary>
        /// 错误消息
        /// </summary>
        public string ErrMSG
        {
            get { return this.errMSG; }
            set { this.errMSG = value; }
        }
        #endregion

        #region 公共方法
        /// <summary>
        /// 获取图片信息
        /// </summary>
        /// <param name="imagePath">图片地址</param>
        /// <returns>成功true失败false</returns>
        public bool GetImage(string imagePath)
        {
            try
            {
                System.Drawing.Image image = System.Drawing.Image.FromFile(imagePath);
                this.width = image.Width;
                this.height = image.Height;
                image.Dispose();

                FileStream fs = new FileStream(imagePath, FileMode.Open, FileAccess.Read);
                this.size = (int)fs.Length;
                fs.Close();

                return true;
            }
            catch (Exception ex)
            {
                this.errMSG = ex.ToString();
                return false;
            }
        }

        /// <summary>
        /// 按宽X长比例切图
        /// </summary>
        /// <param name="imagePath">源图地址</param>
        /// <param name="savePath">新图地址</param>
        /// <param name="cutWidth">宽度</param>
        /// <param name="cutHeight">高度</param>
        /// <returns>成功true失败false</returns>
        public bool CutImageCustom(string imagePath, string savePath, int cutWidth, int cutHeight)
        {
            try
            {
                System.Drawing.Image objImage = System.Drawing.Image.FromFile(imagePath);
                float x = objImage.Width;
                float y = objImage.Height;

                float xPercent = x / cutWidth;
                float yPercent = y / cutHeight;

                if (xPercent < yPercent)
                {
                    this.width = (int)((x * cutHeight) / y);
                    this.height = cutHeight;
                }
                else
                {
                    this.width = cutWidth;
                    this.height = (int)((cutWidth * y) / x);
                }

                System.Drawing.Image newimage = new Bitmap(objImage.Width, objImage.Height, PixelFormat.Format32bppRgb);
                Graphics g = Graphics.FromImage(newimage);
                g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
                g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                g.DrawImage(objImage, 0, 0, objImage.Width, objImage.Height);
                g.Dispose();

                System.Drawing.Image thumbImage = newimage.GetThumbnailImage(this.width, this.height, null, IntPtr.Zero);
                thumbImage.Save(savePath, objImage.RawFormat);

                objImage.Dispose();
                newimage.Dispose();
                thumbImage.Dispose();

                FileStream fs = new FileStream(savePath, FileMode.Open, FileAccess.Read);
                this.size = (int)fs.Length;
                fs.Close();

                return true;
            }
            catch (Exception ex)
            {
                this.errMSG = ex.ToString();
                return false;
            }
        }

        /// <summary>
        /// 将图片缩放到指定的宽度
        /// </summary>
        /// <param name="imagePath">源图地址</param>
        /// <param name="savePath">新图地址</param>
        /// <param name="square">宽度</param>
        /// <returns>成功true失败false</returns>
        public bool CutImageByWidth(string imagePath, string savePath, int square)
        {
            try
            {
                int cutWidth = square;

                System.Drawing.Image objImage = System.Drawing.Image.FromFile(imagePath);
                float x = objImage.Width;
                float y = objImage.Height;

                if (x <= square)
                {
                    objImage.Save(savePath);
                    return true;
                }
                this.width = cutWidth;
                this.height = (int)((cutWidth * y) / x);

                System.Drawing.Image newimage = new Bitmap(objImage.Width, objImage.Height, PixelFormat.Format32bppRgb);
                Graphics g = Graphics.FromImage(newimage);
                g.DrawImage(objImage, 0, 0, objImage.Width, objImage.Height);
                g.Dispose();
                System.Drawing.Image thumbImage = newimage.GetThumbnailImage(this.width, this.height, null, IntPtr.Zero);
                thumbImage.Save(savePath, objImage.RawFormat);

                objImage.Dispose();
                newimage.Dispose();
                thumbImage.Dispose();

                FileStream fs = new FileStream(savePath, FileMode.Open, FileAccess.Read);
                this.size = (int)fs.Length;
                fs.Close();

                return true;
            }
            catch (Exception ex)
            {
                this.errMSG = ex.ToString();
                return false;
            }
        }

        /// <summary>
        /// 将图片缩放到指定的高度
        /// </summary>
        /// <param name="imagePath">源图地址</param>
        /// <param name="savePath">新图地址</param>
        /// <param name="square">高度</param>
        /// <returns>成功true失败false</returns>
        public bool CutImageByHeight(string imagePath, string savePath, int square)
        {
            try
            {
                int cutHeight = square;

                System.Drawing.Image objImage = System.Drawing.Image.FromFile(imagePath);
                float x = objImage.Width;
                float y = objImage.Height;

                this.height = cutHeight;
                this.width = (int)((cutHeight * x) / y);

                System.Drawing.Image newimage = new Bitmap(objImage.Width, objImage.Height, PixelFormat.Format32bppRgb);
                Graphics g = Graphics.FromImage(newimage);
                g.DrawImage(objImage, 0, 0, objImage.Width, objImage.Height);
                g.Dispose();
                System.Drawing.Image thumbImage = newimage.GetThumbnailImage(this.width, this.height, null, IntPtr.Zero);
                thumbImage.Save(savePath, objImage.RawFormat);

                objImage.Dispose();
                newimage.Dispose();
                thumbImage.Dispose();

                FileStream fs = new FileStream(savePath, FileMode.Open, FileAccess.Read);
                this.size = (int)fs.Length;
                fs.Close();

                return true;
            }
            catch (Exception ex)
            {
                this.errMSG = ex.ToString();
                return false;
            }
        }

        /// <summary>
        /// 将图片缩放到指定的大小[只切一边：取图片中间部分]
        /// </summary>
        /// <param name="imagePath">源图地址</param>
        /// <param name="savePath">新图地址</param>
        /// <param name="height">高度</param>
        /// <param name="width">宽度</param>
        /// <returns>成功true失败false</returns
        public bool CutImageBySize(string imagePath, string savePath, int width, int height)
        {
            try
            {
                this.width = width;
                this.height = height;
                int cutWidth = 0;
                int cutHeight = 0;

                System.Drawing.Image objImage = System.Drawing.Image.FromFile(imagePath);

                if ((float)objImage.Width / (float)objImage.Height > (float)this.width / (float)this.height)
                {
                    cutWidth = objImage.Height * this.width / this.height;
                    cutHeight = objImage.Height;
                }
                else
                {
                    cutWidth = objImage.Width;
                    cutHeight = objImage.Width * this.height / this.width;
                }

                System.Drawing.Image newimage = new Bitmap(cutWidth, cutHeight);
                Graphics g = Graphics.FromImage(newimage);
                g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
                g.Clear(Color.Transparent);

                Rectangle destRect = new Rectangle(0, 0, cutWidth, cutHeight);
                Rectangle srcRect = new Rectangle((int)(objImage.Width - cutWidth) / 2, (int)((objImage.Height - cutHeight) / 2), cutWidth, cutHeight);
                GraphicsUnit units = GraphicsUnit.Pixel;
                g.DrawImage(objImage, destRect, srcRect, units);
                g.Dispose();
                System.Drawing.Image thumbImage = newimage.GetThumbnailImage(this.width, this.height, null, IntPtr.Zero);
                thumbImage.Save(savePath, objImage.RawFormat);

                objImage.Dispose();
                newimage.Dispose();
                thumbImage.Dispose();

                FileStream fs = new FileStream(savePath, FileMode.Open, FileAccess.Read);
                this.size = (int)fs.Length;
                fs.Close();

                return true;
            }
            catch (Exception ex)
            {
                this.errMSG = ex.ToString();
                return false;
            }
        }

        /// <summary>
        /// 将图片剪切到一个正方形
        /// </summary>
        /// <param name="imagePath">源图地址</param>
        /// <param name="savePath">新图地址</param>
        /// <param name="square">正方形边长</param>
        /// <returns>成功true失败false</returns>
        public bool CutImageSquare(string imagePath, string savePath, int square)
        {
            try
            {
                this.width = square;
                this.height = square;
                int cutWidth = square;
                int cutHeight = square;

                System.Drawing.Image objImage = System.Drawing.Image.FromFile(imagePath);

                if (objImage.Width >= objImage.Height)
                {
                    cutWidth = objImage.Height;
                    cutHeight = objImage.Height;
                }
                else
                {
                    cutWidth = objImage.Width;
                    cutHeight = objImage.Width;
                }

                System.Drawing.Image newimage = new Bitmap(cutWidth, cutHeight, PixelFormat.Format32bppRgb);
                Graphics g = Graphics.FromImage(newimage);
                g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
                g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;

                Rectangle destRect = new Rectangle(0, 0, cutWidth, cutHeight);
                Rectangle srcRect = new Rectangle(0, 0, cutWidth, cutHeight);
                GraphicsUnit units = GraphicsUnit.Pixel;

                g.DrawImage(objImage, destRect, srcRect, units);
                g.Dispose();
                System.Drawing.Image thumbImage = newimage.GetThumbnailImage(this.width, this.height, null, IntPtr.Zero);
                thumbImage.Save(savePath, objImage.RawFormat);

                objImage.Dispose();
                newimage.Dispose();
                thumbImage.Dispose();

                FileStream fs = new FileStream(savePath, FileMode.Open, FileAccess.Read);
                this.size = (int)fs.Length;
                fs.Close();

                return true;
            }
            catch (Exception ex)
            {
                this.errMSG = ex.ToString();
                return false;
            }
        }

        #region 处理图片长宽显示
        public static void GetProperSize(int trueWidth, int trueHeight, int placeWidth, int placeHeight, out int showWidth, out int showHeight)
        {
            if (trueHeight < placeHeight && trueWidth < placeWidth)
            {
                showHeight = trueHeight;
                showWidth = trueWidth;
            }
            else
            {
                float x = (float)trueWidth;
                float y = (float)trueHeight;

                float xPercent = x / placeWidth;
                float yPercent = y / placeHeight;

                if (xPercent < yPercent)
                {
                    showWidth = (int)((x * placeHeight) / y);
                    showHeight = placeHeight;
                }
                else
                {
                    showWidth = placeWidth;
                    showHeight = (int)((placeWidth * y) / x);
                }
            }
        }
        #endregion

        #region [newImageCut]
        /// <summary>
        /// 生成缩略图
        /// </summary>
        /// <param name="originalImagePath">源图路径（物理路径）</param>
        /// <param name="thumbnailPath">缩略图路径（物理路径）</param>
        /// <param name="width">缩略图宽度</param>
        /// <param name="height">缩略图高度</param>
        /// <param name="mode">生成缩略图的方式</param>   
        public void MakeThumbnail(string originalImagePath, string thumbnailPath, int width, int height, string mode)
        {
            System.Drawing.Image originalImage = System.Drawing.Image.FromFile(originalImagePath);

            int towidth = width;
            int toheight = height;

            int x = 0;
            int y = 0;
            int ow = originalImage.Width;
            int oh = originalImage.Height;

            switch (mode)
            {
                case "HW"://指定高宽缩放（可能变形）           
                    break;
                case "W"://指定宽，高按比例             
                    toheight = originalImage.Height * width / originalImage.Width;
                    break;
                case "H"://指定高，宽按比例
                    towidth = originalImage.Width * height / originalImage.Height;
                    break;
                case "Cut"://指定高宽裁减（不变形）           
                    if ((double)originalImage.Width / (double)originalImage.Height > (double)towidth / (double)toheight)
                    {
                        oh = originalImage.Height;
                        ow = originalImage.Height * towidth / toheight;
                        y = 0;
                        x = (originalImage.Width - ow) / 2;
                    }
                    else
                    {
                        ow = originalImage.Width;
                        oh = originalImage.Width * height / towidth;
                        x = 0;
                        y = (originalImage.Height - oh) / 2;
                    }
                    break;
                default:
                    break;
            }

            //新建一个bmp图片
            System.Drawing.Image bitmap = new System.Drawing.Bitmap(towidth, toheight);

            //新建一个画板
            System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bitmap);

            //设置高质量插值法
            g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;

            //设置高质量,低速度呈现平滑程度
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;

            //清空画布并以透明背景色填充
            g.Clear(System.Drawing.Color.Transparent);

            //在指定位置并且按指定大小绘制原图片的指定部分
            g.DrawImage(originalImage, new System.Drawing.Rectangle(0, 0, towidth, toheight),
                new System.Drawing.Rectangle(x, y, ow, oh),
                System.Drawing.GraphicsUnit.Pixel);

            try
            {
                //以jpg格式保存缩略图
                bitmap.Save(thumbnailPath, System.Drawing.Imaging.ImageFormat.Jpeg);
            }
            catch (System.Exception e)
            {
                throw e;
            }
            finally
            {
                originalImage.Dispose();
                bitmap.Dispose();
                g.Dispose();
            }
        }

        public void CreateCheckCodeImage(string checkCode)
        {
            if (checkCode == null || checkCode.Trim() == String.Empty)
                return;
            System.Drawing.Bitmap image = new System.Drawing.Bitmap((int)Math.Ceiling((checkCode.Length * 12.5)), 22);
            Graphics g = Graphics.FromImage(image);
            try
            {
                //生成随机生成器 
                Random random = new Random();
                //清空图片背景色 
                g.Clear(Color.White);
                //画图片的背景噪音线 
                //for(int i=0; i<25; i++) 
                //{ 
                // int x1 = random.Next(image.Width); 
                // int x2 = random.Next(image.Width); 
                // int y1 = random.Next(image.Height); 
                // int y2 = random.Next(image.Height); 
                // g.DrawLine(new Pen(Color.Silver), x1, y1, x2, y2); 
                //} 
                Font font = new System.Drawing.Font("Arial", 12, (System.Drawing.FontStyle.Bold | System.Drawing.FontStyle.Italic));
                System.Drawing.Drawing2D.LinearGradientBrush brush = new System.Drawing.Drawing2D.LinearGradientBrush(new Rectangle(0, 0, image.Width, image.Height), Color.Blue, Color.DarkRed, 1.2f, true);
                g.DrawString(checkCode, font, brush, 2, 2);
                //画图片的前景噪音点 
                //for(int i=0; i<100; i++) 
                //{ 
                // int x = random.Next(image.Width); 
                // int y = random.Next(image.Height); 
                // image.SetPixel(x, y, Color.FromArgb(random.Next())); 
                //} 
                //画图片的边框线 
                g.DrawRectangle(new Pen(Color.Silver), 0, 0, image.Width - 1, image.Height - 1);
                System.IO.MemoryStream ms = new System.IO.MemoryStream();
                image.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);
                HttpContext.Current.Response.ClearContent();
                HttpContext.Current.Response.ContentType = "image/Gif";
                HttpContext.Current.Response.BinaryWrite(ms.ToArray());
            }
            finally
            {
                g.Dispose();
                image.Dispose();
            }
        }
        #endregion

        #endregion

        /// <summary>
        /// 获取图片指定区域
        /// </summary>
        /// <param name="img"></param>
        /// <param name="top"></param>
        /// <param name="left"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <returns></returns>
        public static byte[] GetPicByPosition(Byte[] srcimgbyte, int top, int left, int width, int height)
        {
            Image srcimg;
            using (MemoryStream ms = new MemoryStream(srcimgbyte))
            {
                srcimg = new Bitmap(ms);
            }

            int iwidth = 400;
            int iheight = 300;
            int newWidth = 400;
            int newHeight = 300;

            if (srcimg.Width > 0 && srcimg.Height > 0)
            {
                if (srcimg.Width / srcimg.Height >= iwidth / iheight)
                {
                    if (srcimg.Width > iwidth)
                    {
                        newWidth = iwidth;
                        newHeight = iheight;
                    }
                    else
                    {
                        newWidth = srcimg.Width;
                        newHeight = srcimg.Height;
                    }
                }
                else
                {
                    if (srcimg.Height > iheight)
                    {
                        newHeight = iheight;
                        newWidth = (srcimg.Width * iheight) / srcimg.Height;
                    }
                    else
                    {
                        newWidth = srcimg.Width;
                        newHeight = srcimg.Height;
                    }
                }
            }           

            float scaleX = (float)srcimg.Width / (float) newWidth;
            float scaleY = (float)srcimg.Height / (float)newHeight;

            top = Convert.ToInt32(Math.Round(top * scaleY));
            left = Convert.ToInt32(Math.Round(left * scaleX));

            width = Convert.ToInt32(Math.Round(width * scaleX));
            height = Convert.ToInt32(Math.Round(height * scaleY));

            Image newImg = new Bitmap(width, height);
            using (Graphics graphic = Graphics.FromImage(newImg))
            {
                graphic.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                graphic.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                graphic.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
                graphic.Clear(Color.Transparent);
                graphic.DrawImage(srcimg, new Rectangle(0, 0, width, height), new Rectangle(left, top, width, height), GraphicsUnit.Pixel);
            }
            using (MemoryStream newms = new MemoryStream())
            {
                newImg.Save(newms, ImageFormat.Jpeg);

                return newms.ToArray();
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="MS"></param>
        /// <param name="savePath"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        public static void SavePicByPath(byte[] MS, string savePath, int width)
        {
            if (!Directory.Exists(Path.GetDirectoryName(savePath)))
            {
                Directory.CreateDirectory(Path.GetDirectoryName(savePath));
            }
            Image img;
            using (MemoryStream ms = new MemoryStream(MS))
            {
                img = new Bitmap(ms);
            }
          
            Image newImg;
            if (width < img.Width)
            {
                newImg = new Bitmap(width, width * img.Height / img.Width);
            }
            else
            {
                newImg = new Bitmap(img.Width, img.Height);
            }
            
            using (Graphics graphic = Graphics.FromImage(newImg))
            {
                graphic.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                graphic.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                graphic.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
                graphic.Clear(Color.Transparent);
                graphic.DrawImage(img, new Rectangle(0, 0, newImg.Width, newImg.Height), new Rectangle(0, 0, img.Width, img.Height), GraphicsUnit.Pixel);
                ImageCodecInfo Ci = GetCodecInfo(Path.GetExtension(savePath));
                if (Ci == null)
                {
                    newImg.Save(savePath);
                    return;
                }
                EncoderParameter p = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 85L);
                EncoderParameters ps = new EncoderParameters(1);
                ps.Param[0] = p;
                newImg.Save(savePath, Ci, ps);
            }           
        }

        private static ImageCodecInfo GetCodecInfo(string FilenameExtension)
        {
            if (FilenameExtension.ToUpper() == ".GIF")
            {
                FilenameExtension = ".JPG";
            }
            ImageCodecInfo[] CodecInfo = ImageCodecInfo.GetImageEncoders();
            foreach (ImageCodecInfo ici in CodecInfo)
            {
                if (ici.FilenameExtension.IndexOf(FilenameExtension.ToUpper().Trim()) > -1)
                {
                    return ici;
                }
            }
            return null;
        }
    }
}
